/*
 * Copyright (C) 2014-2016 Qiujuer <qiujuer@live.cn>
 * WebSite http://www.qiujuer.net
 * Author qiujuer
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.qiujuer.genius.ui.widget;

import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.Image;
import ohos.agp.components.element.Element;
import ohos.app.Context;
import ohos.multimodalinput.event.TouchEvent;

import net.qiujuer.genius.ui.AttrValue;
import net.qiujuer.genius.ui.Ui;
import net.qiujuer.genius.ui.drawable.TouchEffectDrawable;
import net.qiujuer.genius.ui.drawable.effect.EffectFactory;
import net.qiujuer.genius.ui.drawable.factory.ClipFilletFactory;

/**
 * This is touch effect ImageView
 * Include 'Auto' 'Ease' 'Press' 'Ripple' effect to touch
 * <p>
 * <p><strong>XML attributes</strong></p>
 * <p>
 */
public class ImageView extends Image implements TouchEffectDrawable.PerformClicker,
    TouchEffectDrawable.PerformLongClicker, Component.TouchEventListener {
    private TouchEffectDrawable mTouchDrawable;

    public ImageView(Context context) {
        this(context, null);
    }

    public ImageView(Context context, AttrSet attrs) {
        this(context, attrs, 0);
    }

    public ImageView(Context context, AttrSet attrs, int defStyleAttr) {
        super(context, attrs, null);
        setTouchEventListener(this);
        init(attrs, defStyleAttr, defStyleAttr);
    }

    private void init(AttrSet attrs, int defStyleAttr, int defStyleRes) {
        if (attrs == null) {
            return;
        }
        int touchEffect = AttrValue.get(attrs, "gTouchEffect", EffectFactory.TOUCH_EFFECT_NONE);
        int touchColor = AttrValue.get(attrs, "gTouchColor", Ui.TOUCH_PRESS_COLOR);
        int touchRadius = AttrValue.getDimension(attrs, "gTouchCornerRadius", 4);
        int touchRadiusTL = AttrValue.getDimension(attrs, "gTouchCornerRadiusTL", touchRadius);
        int touchRadiusTR = AttrValue.getDimension(attrs, "gTouchCornerRadiusTR", touchRadius);
        int touchRadiusBL = AttrValue.getDimension(attrs, "gTouchCornerRadiusBL", touchRadius);
        int touchRadiusBR = AttrValue.getDimension(attrs, "gTouchCornerRadiusBR", touchRadius);
        float touchDurationRate = AttrValue.get(attrs, "gTouchDurationRate", 1.0f);
        boolean enabled = AttrValue.get(attrs, "android:enabled", touchEffect != EffectFactory.TOUCH_EFFECT_NONE);
        int interceptEvent = AttrValue.get(attrs, "gInterceptEvent", 0x0001);

        // Initial  TouchEffectDrawable
        if (touchEffect != 0) {
            TouchEffectDrawable touchEffectDrawable = new TouchEffectDrawable();
            touchEffectDrawable.setColor(touchColor);
            touchEffectDrawable.setEffect(EffectFactory.creator(touchEffect));
            touchEffectDrawable.setEnterDuration(touchDurationRate);
            touchEffectDrawable.setExitDuration(touchDurationRate);
            touchEffectDrawable.setInterceptEvent(interceptEvent);
            // Check for IDE preview render to set Touch factory
            float[] radius = new float[]{touchRadiusTL, touchRadiusTL, touchRadiusTR, touchRadiusTR,
                touchRadiusBR, touchRadiusBR, touchRadiusBL, touchRadiusBL};
            ClipFilletFactory touchFactory = new ClipFilletFactory(radius);
            touchEffectDrawable.setClipFactory(touchFactory);
            setTouchDrawable(touchEffectDrawable);
        }

        // Change enabled
        setEnabled(enabled);
    }

    /**
     * Get the TouchEffect drawable, you can set parameters in this
     *
     * @return TouchEffectDrawable TouchEffectDrawable
     */
    public TouchEffectDrawable getTouchDrawable() {
        return mTouchDrawable;
    }

    /**
     * In this, you can set TouchEffectDrawable,
     * to init TouchEffectDrawable.
     * <p>
     * If you not need touch effect,
     * you should set NULL.
     * <p>
     * But, if need it,
     *
     * @param touchDrawable TouchEffectDrawable
     */
    public void setTouchDrawable(TouchEffectDrawable touchDrawable) {
        if (mTouchDrawable != touchDrawable) {
            if (mTouchDrawable != null) {
                mTouchDrawable.setCallback(null);
            }
            if (touchDrawable != null) {
                touchDrawable.setCallback(new Element.OnChangeListener() {
                    @Override
                    public void onChange(Element element) {
                    }
                });
                // We must set layer type is View.LAYER_TYPE_SOFTWARE,
                // to support Canvas.clipPath()
                // on Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB
            }
            mTouchDrawable = touchDrawable;
        }
    }

    @Override
    public void postPerformClick() {
    }

    @Override
    public void postPerformLongClick() {
    }

    @Override
    public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
        final TouchEffectDrawable d = mTouchDrawable;
        if (d != null && isEnabled()) {
            d.onTouch(touchEvent);
        }
        return false;
    }
}
